package cn.csc.module.order.controller.admin.order;

import cn.csc.framework.common.pojo.CommonResult;
import cn.csc.framework.common.pojo.PageResult;
import cn.csc.framework.excel.core.util.ExcelUtils;
import cn.csc.framework.operatelog.core.annotations.OperateLog;
import cn.csc.module.order.controller.admin.addr.vo.OrderAddrUpdateReqVO;
import cn.csc.module.order.controller.admin.item.vo.OrderItemBaseVO;
import cn.csc.module.order.controller.admin.item.vo.OrderWithItemPageReqVO;
import cn.csc.module.order.controller.admin.order.vo.*;
import cn.csc.module.order.convert.addr.OrderAddrConvert;
import cn.csc.module.order.convert.item.OrderItemConvert;
import cn.csc.module.order.convert.order.OrderConvert;
import cn.csc.module.order.dal.dataobject.addr.OrderAddrDO;
import cn.csc.module.order.dal.dataobject.item.OrderItemDO;
import cn.csc.module.order.dal.dataobject.order.OrderDO;
import cn.csc.module.order.enums.ErrorCodeConstants;
import cn.csc.module.order.enums.LogisticsStatusEnum;
import cn.csc.module.order.enums.OrderStatusEnum;
import cn.csc.module.order.service.addr.OrderAddrService;
import cn.csc.module.order.service.item.OrderItemService;
import cn.csc.module.order.service.order.OrderService;
import cn.csc.module.order.util.Kuaidi100Util;
import cn.csc.module.shoppingCard.api.card.CardApi;
import cn.csc.module.shoppingCard.api.card.dto.CardRespDTO;
import cn.csc.module.shoppingCard.api.transaction.CardTransactionApi;
import cn.csc.module.shoppingCard.api.transaction.dto.CardTransactionRespDTO;
import cn.csc.module.system.api.ip.KuaiDi100CompanyCodeApi;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.shaded.com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.kuaidi100.sdk.pojo.HttpResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Operation;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static cn.csc.framework.common.pojo.CommonResult.success;
import static cn.csc.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;

@Api(tags = "V2管理后台 - 订单信息")
@RestController
@RequestMapping("/order/v2")
@Validated
@Slf4j
public class OrderV2Controller {

    @Resource
    private OrderService orderService;
    @Resource
    private OrderItemService orderItemService;
    @Resource
    private OrderAddrService orderAddrService;

    @Autowired
    private CardTransactionApi cardTransactionApi;
    @Autowired
    private CardApi cardApi;
    @Autowired
    private KuaiDi100CompanyCodeApi kuaiDi100CompanyCodeApi;
    @Value("${csc.wl.kuaidi100.customer}")
    private String customer;
    @Value("${csc.wl.kuaidi100.key}")
    private String key ;

    @GetMapping("/get")
    @ApiOperation("获得订单信息")
    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = BigInteger.class)
    @PreAuthorize("@ss.hasPermission('order::query')")
    public CommonResult<OrderInfoRespVO> get(@RequestParam(value = "orderItemIds") String orderItemIds) {
        log.info("[OrderV2Controller][get][ids]=={}",orderItemIds);
        List<String> list= Arrays.stream(orderItemIds.split("-")).collect(Collectors.toList());
        List<BigInteger> ids=list.stream().map(BigInteger::new ).collect(Collectors.toList());

        //订单项信息
        List<OrderItemDO> spuList= orderItemService.getItemList(ids);
        BigDecimal total = spuList.stream().map( OrderItemDO::getSpuTotalAmount ).reduce(BigDecimal.ZERO, BigDecimal::add);
        //订单详情信息，
        OrderDO orderDO  = orderService.get(spuList.get(0).getOrderId());
        OrderInfoRespVO orderInfoRespVO= OrderConvert.INSTANCE.convertInfo(orderDO);
        orderInfoRespVO.setItemVOList(OrderItemConvert.INSTANCE.convertList(spuList))
                        .setDeliveryTime(spuList.get(0).getDeliveryTime())
                        .setFinallyTime(spuList.get(0).getFinallyTime())
                        .setTotal(total)
                        .setCardPayAmount(spuList.stream()
                                .map(OrderItemDO::getCardPayAmount)
                                .filter(Objects::nonNull)
                                .reduce(BigDecimal.ZERO, BigDecimal::add))
                        .setSpuActualAmount(spuList.stream().map(OrderItemDO::getSpuActualAmount).reduce(BigDecimal.ZERO, BigDecimal::add))
                        .setOrderStatus(spuList.get(0).getOrderStatus());
        //订单地址信息
        OrderAddrDO orderAddrDO=orderAddrService.getAddrByOrderId(spuList.get(0).getOrderId());
        orderInfoRespVO.setOrderAddr(OrderAddrConvert.INSTANCE.convert(orderAddrDO));

        if(orderDO.getPayType()==1 || orderDO.getPayType()==2){
            List<BigInteger> cardIds=cardTransactionApi.getByOrderIds(Arrays.asList(orderDO.getId())).getCheckedData().stream().map(CardTransactionRespDTO::getCardId).distinct().collect(Collectors.toList());
            orderInfoRespVO.setShoppingCardId(cardApi.listByCardId(cardIds).getCheckedData().stream().map(CardRespDTO::getCardNumber).distinct().collect(Collectors.toList()));
        }
        if(orderDO.getDeliveryType()==1){
            //物流信息
            log.info("[OrderV2Controller][get][httpResult]{}{}",orderAddrDO.getLogisticsCom(),orderAddrDO.getLogisticsNum());
            HttpResult httpResult=new Kuaidi100Util().queryTrack(customer,key,orderAddrDO.getLogisticsCom(),orderAddrDO.getLogisticsNum());
            log.info("[OrderV2Controller][get][httpResult]{}",httpResult);
            if(httpResult!=null && httpResult.getStatus()==200){
                if(JSONObject.parseObject(httpResult.getBody()).get("status")!=null && JSONObject.parseObject(httpResult.getBody()).get("status").equals("200")){
                    String json= JSONObject.parseObject(httpResult.getBody()).get("data").toString();
                    log.info("[OrderV2Controller][get][json]{}",json);
                    Gson gson = new Gson();
                    Type listType = new TypeToken<List<LogisticsVO>>(){}.getType();
                    orderInfoRespVO.setLogisticsVOs(gson.fromJson(json, listType));
                    Integer state=Integer.parseInt(JSONObject.parseObject(httpResult.getBody()).get("state").toString());
                    orderInfoRespVO.setLogisticsStatus(LogisticsStatusEnum.getLable(state));
                    orderInfoRespVO.setLogisticsComName(kuaiDi100CompanyCodeApi.getByCode(orderAddrDO.getLogisticsCom()).getData().getName());
                    orderInfoRespVO.setLogisticsNum(orderAddrDO.getLogisticsNum());
                }
            }

        }

        return success(orderInfoRespVO);
    }


    @GetMapping("/list")
    @ApiOperation("获得订单信息列表")
    @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
    @PreAuthorize("@ss.hasPermission('order::query')")
    public CommonResult<List<OrderRespAdminVO>> getList(@RequestParam("ids") Collection<BigInteger> ids) {
        List<OrderDO> list = orderService.getList(ids);
        return success(OrderConvert.INSTANCE.convertList(list));
    }

    @GetMapping("/page")
    @ApiOperation("获得订单信息分页")
    @PreAuthorize("@ss.hasPermission('order::query')")
    public CommonResult<PageResult<OrderWithItemRespVO>> getPage(@Valid OrderPageReqVO pageVO) {
        log.info("[OrderV2Controller][getPage][pageVO]=={}",pageVO);
        PageResult<OrderWithItemRespVO> pageResult = orderService.selectOrderWithItemsPage(pageVO);
        pageResult.getList();
        log.info("[OrderV2Controller][getPage][pageResult],{}",pageResult);
        return success(pageResult);
    }

    @GetMapping("/export")
    @ApiOperation("导出订单信息 Excel")
    @PreAuthorize("@ss.hasPermission('order::export')")
    @OperateLog(type = EXPORT)
    public void exportExcel(@Valid OrderWithItemPageReqVO pageVO,
              HttpServletResponse response) throws IOException {
        List<OrderItemBaseVO> list = orderItemService.getExportList(pageVO);
        // 导出 Excel
        List<BigInteger> orderIds = list.stream().map(OrderItemBaseVO::getOrderId).collect(Collectors.toList());
        List<OrderDO> order=orderService.getList(orderIds);
        List<OrderExcelVO> datas =new ArrayList<>();
        for(OrderItemBaseVO data:list){
            OrderExcelVO vo=OrderConvert.INSTANCE.convert02(data);
            OrderDO orderDO=order.stream().filter(e -> e.getId().equals(data.getOrderId())).findFirst().orElse(null);
            vo.setOutTradeNo(orderDO.getOutTradeNo())
              .setId(String.valueOf(data.getOrderId()))
              .setTotal(data.getSpuTotalAmount())
              .setNickName(orderDO.getNickName())
              .setDeliveryTime(data.getDeliveryTime()!=null?data.getDeliveryTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")):"")
              .setPayTime(data.getPayTime()!=null?data.getPayTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")):"")
              .setFinallyTime(data.getFinallyTime()!=null?data.getFinallyTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")):"")
              .setAllCount(data.getCount());
            datas.add(vo);
        }
        ExcelUtils.write(response, "商城订单信息.xls", "数据", OrderExcelVO.class, datas);
    }
    /**
     * 发货
     */
    @PutMapping("/delivery")
    @Operation(summary = "根据订单号发货", description = "根据订单号发货")
    @PreAuthorize("@ss.hasPermission('order::update')")
    public CommonResult<Object> delivery(@Valid @RequestBody OrderDeliveryReqVO reqVO) {
        log.info("[OrderV2Controller][delivery][ids]=={}",reqVO);
        log.info("[OrderV2Controller][delivery][customer]=={}",customer);

        //订单项信息
        List<OrderItemDO> spuList= orderItemService.getItemList(reqVO.getOrderItemIds());
        log.info("[OrderV2Controller][delivery][order]=={}",spuList);
        if (spuList==null ) {
            // 订单未支付发货，无法确认发货
            return CommonResult.error(ErrorCodeConstants.ORDER_NOT_EXISTS);
        }
        if ( spuList.get(0).getOrderStatus()!= OrderStatusEnum.PAYED.value()) {
            // 订单未支付发货，无法确认发货
            return CommonResult.error(ErrorCodeConstants.ORDER_NOT_PAYED);
        }
        //如查询不到物流信息，按接口返回进行提示
        if(reqVO.getDeliveryType()==1){
            HttpResult httpResult=new Kuaidi100Util().queryTrack(customer,key,reqVO.getLogisticsCom(),reqVO.getLogisticsNum());
            log.info("[OrderV2Controller][delivery][httpResult]=={}",httpResult);
            String returnCode=String.valueOf(JSONObject.parseObject(httpResult.getBody()).get("returnCode"));
            if(StringUtil.isNotEmpty(returnCode)){
                if(returnCode.equals("500")){
                    return CommonResult.error(ErrorCodeConstants.ORDER_WL_NODATA_ERROR);
                }
                if(returnCode.equals("400") ||returnCode.equals("408")){
                    return CommonResult.error(ErrorCodeConstants.ORDER_WL_COMPANY_ERROR);
                }
                if(returnCode.equals("501")|| returnCode.equals("502")
                        || returnCode.equals("503") || returnCode.equals("601")){
                    return CommonResult.error(ErrorCodeConstants.ORDER_WL_SYSTEM_ERROR);
                }
            }
        }

        // 发货
        //修改子项的发货状态
        List<OrderUpdateDeliveryReqVO> updateReqVO= new ArrayList<>();
        reqVO.getOrderItemIds().stream().forEach(item ->{
            OrderUpdateDeliveryReqVO vo= new OrderUpdateDeliveryReqVO();
                    vo.setId(item);
                    vo.setOrderStatus(OrderStatusEnum.CONSIGNMENT.value());
                    vo.setDeliveryType(reqVO.getDeliveryType());
                    vo.setDeliveryTime(LocalDateTime.now());
                    vo.setDeliveryFile(reqVO.getDeliveryFile());
                    updateReqVO.add(vo);
        });
        orderItemService.updateBatch(updateReqVO);

        OrderDO orderDO = new OrderDO();
        orderDO.setId(spuList.get(0).getOrderId())
               .setOrderStatus(OrderStatusEnum.CONSIGNMENT.value())
               .setDeliveryTime(LocalDateTime.now())
                .setDeliveryType(reqVO.getDeliveryType())
               .setDeliveryFile(reqVO.getDeliveryFile());
        orderService.updateOrderStatus(orderDO);
        //修改物流信息
        if(reqVO.getDeliveryType()==1){
            List<OrderAddrUpdateReqVO> updateAddReqVO = new ArrayList<>();
            reqVO.getOrderItemIds().stream().forEach(item ->{
                OrderAddrUpdateReqVO vo= new OrderAddrUpdateReqVO();
                vo.setLogisticsCom(reqVO.getLogisticsCom());
                vo.setLogisticsNum(reqVO.getLogisticsNum());
                vo.setOrderItemId(item);
                vo.setOrderId(spuList.get(0).getOrderId());
                updateAddReqVO.add(vo);
            });
            orderAddrService.updateBatch(updateAddReqVO);
        }
        return success(orderDO.getId());
    }

}
